package com.oa.tools.jobs;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import com.landray.kmss.sys.organization.webservice.in.main.OAWebServiceInClient;
import com.oa.tools.dao.FlowLogDAO;
import com.oa.tools.dao.LbpmProcessDAO;
import com.oa.tools.dao.OAFlowInstanceDAO;
import com.oa.tools.dao.OAStaffLevelDAO;
import com.oa.tools.dao.OrgElementDAO;
import com.oa.tools.dao.OrgElementWithPersonDAO;
import com.oa.tools.dao.PersonDAO;
import com.oa.tools.dao.ProjectAccountDAO;
import com.oa.tools.dao.StampDAO;
import com.oa.tools.entity.OAStaffLevel;
import com.oa.tools.entity.OrgElement;
import com.oa.tools.entity.OrgElementWithPerson;
import com.oa.tools.entity.Person;
import com.oa.tools.hr.XRXSReqClient;
import com.oa.tools.hr.XRXSReqClient.XRXSDept;
import com.oa.tools.hr.XRXSReqClient.XRXSPerson;
import com.oa.tools.utils.DateUtil;
import com.oa.tools.utils.ExceptionUtil;
import com.oa.tools.utils.FileUtil;
import com.oa.tools.utils.MailUtil;
import com.oa.tools.utils.MailUtil.UpdateEmailRequest;
import com.oa.tools.utils.StringUtil;
import com.oa.tools.utils.SysConfig;

import tk.mybatis.mapper.entity.Example;

@Service
public class SynchronizeJob implements Runnable {

	public static boolean jobRunningFlag = false;
	private ScheduledFuture<?> future;
	private long lastestDateMill = System.currentTimeMillis() - 1000L * 60 * 60 * 12*2*10;
	private String cronStr = "0 0/1 * * * ?";

	@Autowired
	private ThreadPoolTaskScheduler threadPoolTaskScheduler;
	@Autowired
	OAFlowInstanceDAO oAFlowInstanceDAO;
	@Autowired
	FlowLogDAO flowLogDAO;
	@Autowired
	PersonDAO personDAO;
	@Autowired
	OAStaffLevelDAO oAStaffLevelDAO;
	@Autowired
	StampDAO stampDAO;
	@Autowired
	OrgElementDAO orgElementDAO;
	@Autowired
	OrgElementWithPersonDAO orgElementWithPersonDAO;
	@Autowired
	LbpmProcessDAO lbpmProcessDAO;
	@Autowired
	ProjectAccountDAO projectAccountDAO;
	
	
	public static final Logger logger = LoggerFactory.getLogger(SynchronizeJob.class);
	private Map<String,FlowHandlerTaskBase> taskMap = new HashMap<>();
	
	public Map<String, FlowHandlerTaskBase> getTaskMap() {
		return taskMap;
	}


	public long getLastestDateMill() {
		return this.lastestDateMill;
	}

	public void setLastestDateMill(long lastestDateMill) {
		this.lastestDateMill = lastestDateMill;
	}


	@Override
	public void run() {
		try {
			if(!jobRunningFlag) {
				jobRunningFlag = true;
				//long lastestDateMill_tmp = this.lastestDateMill;
				this.lastestDateMill = System.currentTimeMillis() - 1000L * 60 * 60 * 12;
				
				Map<String,Object> messages = XRXSReqClient.getAllMessages();
				List<Map<String,Object>> params = (List<Map<String, Object>>) messages.get("data");
				for(Map<String,Object> param :params) {
					synchronizeWhenCallBack(param);
				}
				
				synchronizeWhenTimeout();
				logger.info("组织架构同步任务执行完成"+System.currentTimeMillis());
			}else{
				logger.info("上一次组织架构同步任务执行未完成");
				return ;
			}
			
			jobRunningFlag = false;
		} catch (Throwable e) {
			jobRunningFlag = false;
			e.printStackTrace();
		}

	}

	public String startCron() {
		future = threadPoolTaskScheduler.schedule(this, new CronTrigger(cronStr));
		return "startCron";
	}

	public String stopCron() {
		if (future != null) {
			future.cancel(true);
		}
		return "stopCron";
	}

	public String update(String cron) {
		stopCron();// 先停止，在开启.
		this.cronStr = cron;
		future = threadPoolTaskScheduler.schedule(this, new CronTrigger(cron));
		return "changeCron10";
	}

	public String getCronStr() {
		return cronStr;
	}

	public void setCronStr(String cronStr) {
		this.cronStr = cronStr;
	}
	
	private void addDepartment(Map<String,Object> param) {
		
		String departmentId = StringUtil.parseString(param.get("departmentId"));
		String code = StringUtil.parseString(param.get("code"));
		String name = StringUtil.parseString(param.get("name"));
		String parentId = StringUtil.parseString(param.get("parentId"));
		String adminId = StringUtil.parseString(param.get("adminId"));//部门领导
		try {
			
			OAWebServiceInClient.addDepartment(departmentId,code, name, parentId,adminId);
			
			/**
			 * 不自动更新部门，由于频次较低，且风险较高，人为判断并更新部门
			 */
			StringBuilder content = new StringBuilder();
			content.append("<h1>人力系统新增部门，请注意同步手工维护OA系统和企业邮箱的组织架构</h1><br/><pre>");
			content.append("部门ID：");content.append(departmentId);content.append("\r\n");
			content.append("部门编号：");content.append(code);content.append("\r\n");
			content.append("部门名称：");content.append(name);content.append("\r\n");
			if(!StringUtil.isBlank(parentId)) {
				XRXSDept parentDept= XRXSReqClient.getAllDepts(parentId,false).get(parentId);
				content.append("上级部门：");content.append(parentDept.getName());content.append("\r\n");
			}else {
				content.append("上级部门：");content.append("沣邦融资租赁（上海）有限公司");content.append("\r\n");
			}
			
			if(StringUtil.isBlank(adminId)) {
				XRXSPerson xrxsPerson = XRXSReqClient.getUserDetail(adminId);
				String adminName = xrxsPerson.getName();
				String fdNo = xrxsPerson.getFdNo();
				String title = xrxsPerson.getTitle();
				String rank = xrxsPerson.getRank();
				content.append("负责人工号：");content.append(fdNo);content.append("\r\n");
				content.append("负责人姓名：");content.append(adminName);content.append("\r\n");
				content.append("负责人职级：");content.append(rank);content.append("\r\n");
				content.append("负责人岗位：");content.append(title);content.append("\r\n");
			}else {
				content.append("未设置部门负责人");content.append("\r\n");
			}
		
			content.append("</pre>");
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
			receiveMailAccounts.clear();
			receiveMailAccounts.add("sushaolei@fengbangleasing.com");
	    	MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", content.toString());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void updateDepartment(Map<String,Object> param) {
		
		String departmentId = StringUtil.parseString(param.get("departmentId"));
		String code = StringUtil.parseString(param.get("code"));
		String name = StringUtil.parseString(param.get("name"));
		String parentId = StringUtil.parseString(param.get("parentId"));
		String adminId = StringUtil.parseString(param.get("adminId"));//部门领导
		try {
			/**
			 * 不自动更新部门，由于频次较低，人为判断并更新部门
			 */
			OAWebServiceInClient.updateDepartment(departmentId,code, name, parentId,adminId);
			
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
			StringBuilder content = new StringBuilder();
			content.append("<h1>人力系统修改部门，请注意同步手工维护OA和邮箱组织架构</h1><br/><pre>");
			content.append("部门ID：");content.append(departmentId);content.append("\r\n");
			content.append("部门编号：");content.append(code);content.append("\r\n");
			content.append("部门名称：");content.append(name);content.append("\r\n");
			
			if(!StringUtil.isBlank(parentId)) {
				XRXSDept parentDept= XRXSReqClient.getAllDepts(parentId,false).get(parentId);
				content.append("上级部门：");content.append(parentDept.getName());content.append("\r\n");
			}else {
				content.append("上级部门：");content.append("沣邦融资租赁（上海）有限公司");content.append("\r\n");
			}
			
			if(StringUtil.isBlank(adminId)) {
				XRXSPerson xrxsPerson = XRXSReqClient.getUserDetail(adminId);
				String adminName = xrxsPerson.getName();
				String fdNo = xrxsPerson.getFdNo();
				String title = xrxsPerson.getTitle();
				String rank = xrxsPerson.getRank();
				content.append("负责人工号：");content.append(fdNo);content.append("\r\n");
				content.append("负责人姓名：");content.append(adminName);content.append("\r\n");
				content.append("负责人职级：");content.append(rank);content.append("\r\n");
				content.append("负责人岗位：");content.append(title);content.append("\r\n");
			}else {
				content.append("未设置部门负责人");content.append("\r\n");
			}
			content.append("</pre>");
	    	MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", content.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void deleteDepartment(Map<String,Object> param) {
		String departmentId = StringUtil.parseString(param.get("departmentId"));
		try {
			/**
			 * 不自动更新部门，由于频次较低，且风险较高，人为判断并更新部门
			 */
			//OAWebServiceInClient.deleteDepartment(departmentId);
			
			StringBuilder content = new StringBuilder();
			content.append("<h1>人力系统删除部门，请注意同步手工维护OA系统和企业邮箱的组织架构</h1><br/><pre>");
			content.append("部门ID：");content.append(departmentId);content.append("\r\n");
			
			Example example = new Example(OrgElement.class);
			example.createCriteria().andEqualTo("fdImportInfo",OAWebServiceInClient.APPNAME+departmentId);
			OrgElement depart = orgElementDAO.selectOneByExample(example);
			String name = depart.getFdName();
			String code = depart.getFdNo();
			content.append("部门名称：");content.append(name);content.append("\r\n");
			content.append("部门编码：");content.append(code);content.append("\r\n");
			content.append("</pre>");
			
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
			receiveMailAccounts.clear();
			receiveMailAccounts.add("sushaolei@fengbangleasing.com");
	    	MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", content.toString());
	    
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
	
	private XRXSPerson addPerson(String employeeId) {
		/*
		 * 查询获取用户详情
		 */
		XRXSPerson xrxsPerson = null;
		try {
			xrxsPerson = XRXSReqClient.getUserDetail(employeeId);
			String departmentId = xrxsPerson.getDepartmentId();
			String name = xrxsPerson.getName();
			String title = xrxsPerson.getTitle();
			String mobile = xrxsPerson.getMobile();
			String tel = xrxsPerson.getTel();
			String fdNo = xrxsPerson.getFdNo();
			String gender = xrxsPerson.getGender();
			String entryDate = xrxsPerson.getEntryDate();
			String hireType = xrxsPerson.getHireType();
			String rank = xrxsPerson.getRank();
			
			
			name = name.replaceAll("\\s+","");
			mobile= mobile.replaceAll("[^0-9]", "");
			tel = ("null".equals(tel) || StringUtil.parseString(tel).equals(""))?"0":tel;
			
			String password = "Fb"+mobile;
			return addPerson(employeeId,departmentId, name, title, mobile, tel, fdNo, gender, entryDate, hireType, rank, password);
		} catch (Exception e) {
			logger.error("addPerson error",e);
		}
		
		return null;
	}
	
 	private XRXSPerson addPerson(String employeeId,String departmentId,String name,String title,String mobile,String tel,String fdNo,String gender,String entryDate,String hireType,String rank,String password){
 		mobile= mobile.replaceAll("[^0-9]", "");
		tel = ("null".equals(tel) || StringUtil.parseString(tel).equals(""))?"0":tel;
 		XRXSPerson xrxsPerson = null;
 		String departmentName = null;
		try {
			
			if(StringUtil.isBlank(departmentId)) {
				departmentId = "company";
				departmentName="沣邦融资租赁(上海)有限公司";
			}else {
				/*
				 * 查询部门信息
				 */
				departmentName= SysConfig.getMap("新入职流程处理配置","XRXS_OA_部门映射").get(departmentId);
				if(StringUtil.isBlank(departmentName)) {
					Map<String,XRXSDept> deptsInfoMap =  XRXSReqClient.getAllDepts(departmentId,false);
					departmentName = deptsInfoMap.get(departmentId).getName();
					Map<String,String> xrxsOaMapping = new HashMap<>();
					xrxsOaMapping.put(departmentId, departmentName);
					SysConfig.setMap("新入职流程处理配置","XRXS_OA_部门映射",xrxsOaMapping);
				}
				
			}
			
			/*
			 * 创建邮箱
			 */
//			String logName = StringUtil.getPinyin(name);
			String logName = MailUtil.createEmail2Ok(name, departmentName, title, mobile, tel, fdNo, gender);
			String email = logName+"@fengbangleasing.com";
			
			/*
			 * 创建OA用户 
			 */
			OAWebServiceInClient.addPerson(employeeId, fdNo, name,gender.equals("男")?"M":"F",logName, password,  mobile, tel, email, departmentId);
			
			/*
			 * 更新XRXS用户邮箱
			 */
			XRXSReqClient.updateUserInfo(employeeId, name, mobile, entryDate, hireType, "工作邮箱", email);
			
			/*
			 * 设置OA用户职级
			 */
			Example example_level = new Example(OAStaffLevel.class);
			example_level.createCriteria().andEqualTo("fdName", rank);
			OAStaffLevel staffLevel = oAStaffLevelDAO.selectOneByExample(example_level);
			if(staffLevel!=null) {
				Person newPerson = new Person();
				newPerson.setFdLoginName(logName);
				newPerson.setFdMobileNo(mobile);
				newPerson.setFdStaffingLevelId(staffLevel.getFdId());
				Example example = new Example(Person.class);
				example.createCriteria().andEqualTo("fdLoginName", logName).andEqualTo("fdMobileNo", mobile);
				personDAO.updateByExampleSelective(newPerson, example);
			}
			
			
			/*
			 * 发送通知邮件（it管理员，人力管理员，员工本人）
			 */
			Set<String> mailManagers = SysConfig.getSysSet("邮箱管理员接收邮箱");
			Set<String> hrManagers = SysConfig.getSysSet("人力管理员接收邮箱");
			Set<String> receiveMailAccounts = new HashSet<String>();
			if(mailManagers==null) {
				receiveMailAccounts.addAll(mailManagers);
			}
			if(hrManagers==null) {
				receiveMailAccounts.addAll(hrManagers);
			}
			receiveMailAccounts.add(email);
			
//			receiveMailAccounts.clear();
//			receiveMailAccounts.add("sushaolei@fengbangleasing.com");
			
			StringBuilder content = new StringBuilder();
			content.append("<h1>欢迎加入沣邦大家庭!</h1><br/><pre>");
			content.append("OA访问地址：\t");content.append("http://oa.fengbangleasing.com");content.append("\r\n");
			content.append("OA登录名：\t");content.append(logName);content.append("\r\n");
			content.append("初始密码：\t");content.append(password);content.append("\r\n");
			content.append("姓名：\t");content.append(name);content.append("\r\n");
			content.append("工号：\t");content.append(fdNo);content.append("\r\n");
			content.append("岗位：\t");content.append(title);content.append("\r\n");
			content.append("职级：\t");content.append(rank);content.append("\r\n");
			content.append("手机：\t");content.append(mobile);content.append("\r\n");
			content.append("部门：\t");content.append(departmentName);content.append("\r\n");
			content.append("邮箱：\t");content.append(email);content.append("\r\n");
			content.append("固话：\t");content.append(tel);content.append("\r\n");
			
			content.append("</pre>");
			content.append("手机端KK下载如下：<br/>");
			content.append("<img src='http://oa-tool.fengbangleasing.com/images/kk-access.png'/><br/>");
			content.append("<img src='http://oa-tool.fengbangleasing.com/images/kk-base-settings.png'/>");
			
	    	MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), name+"-OA账号创建完成通知", content.toString());
		} catch (Exception e) {
			e.printStackTrace();
			StringBuilder content = new StringBuilder();
			content.append("<h1>OA账号创建报错</h1><br/><pre>");
			content.append(ExceptionUtil.getStackTrace(e));
			content.append("</pre>");
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
			receiveMailAccounts.clear();
			receiveMailAccounts.add("sushaolei@fengbangleasing.com");
			try {
				MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), name+"-OA账号创建报错", content.toString());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		
		return xrxsPerson;
	}
 	
 	@SuppressWarnings("unchecked")
	private StringBuilder updatePerson(Map<String,Object> param) {
 		
		String employeeId = StringUtil.parseString(param.get("employeeId"));
		String name = StringUtil.parseString(param.get("name"));
		String mobile = StringUtil.parseString(param.get("mobile"));
		Map<String,Object> fields = (Map<String, Object>) param.get("fields");
		String departmentId = StringUtil.parseString(fields.get("部门"));
		
		StringBuilder content = new StringBuilder();
		
		Example example_tmp = new Example(OrgElement.class);
		example_tmp.createCriteria().andEqualTo("fdIsAvailable", (short)1).andEqualTo("fdImportInfo", OAWebServiceInClient.APPNAME+employeeId).andEqualTo("fdOrgType", 8L);
		OrgElement orgElement1 =  orgElementDAO.selectOneByExample(example_tmp);
		if(orgElement1==null) {
			this.addPerson(employeeId);
			return content.append("当前OA没有找到该用户："+name+",正在准备新建该用户，employeeid="+employeeId) ;
		}
		
		try {
			/*
			 * 获取员工详情,更新OA用户
			 */
			XRXSPerson xrxsPerson = XRXSReqClient.getUserDetail(employeeId);
			String fdNo =  xrxsPerson.getFdNo();
			String gender =xrxsPerson.getGender();
			String title = xrxsPerson.getTitle();
			String rank =  xrxsPerson.getRank();
			String tel =   xrxsPerson.getTel();
			String email = xrxsPerson.getEmail();
			OAWebServiceInClient.updatePerson(employeeId, fdNo, name,gender.equals("男")?"M":"F",mobile, tel,  departmentId);
			
			/*
			 * 设置OA用户职级
			 */
			Example example_level = new Example(OAStaffLevel.class);
			example_level.createCriteria().andEqualTo("fdName", rank);
			OAStaffLevel staffLevel = oAStaffLevelDAO.selectOneByExample(example_level);
			if(staffLevel!=null) {
				Person newPerson = new Person();
				newPerson.setFdMobileNo(mobile);
				newPerson.setFdStaffingLevelId(staffLevel.getFdId());
				Example example = new Example(Person.class);
				example.createCriteria().andEqualTo("fdMobileNo", mobile);
				personDAO.updateByExampleSelective(newPerson, example);
			}
			
			
			/*
			 * 查询部门信息，获取部门名称，更新邮箱信息
			 */
			String departmentName = null;
			if(!StringUtil.isBlank(departmentId)) {
				Map<String,XRXSDept> deptsInfoMap =  XRXSReqClient.getAllDepts(departmentId,false);
				departmentName = StringUtil.parseString(deptsInfoMap.get("departmentId").getName());
			}
			
			UpdateEmailRequest request = new UpdateEmailRequest(email.replace("@fengbangleasing.com", ""),
					name, departmentName, title, mobile, tel, fdNo, gender);
			MailUtil.updateEmail(request);
			
			content.append(name);content.append("-");
			content.append(fdNo);content.append("-");
			content.append(rank==null?"岗位":rank);content.append("-");
			content.append(departmentName==null?"部门":departmentName);content.append("\r\n");
			
		} catch (Exception e) {
			logger.error("updatePerson error",e);
		}
		return content;
	}
 	
 	private void deletePerson(Map<String,Object> param){
 		String employeeId = StringUtil.parseString(param.get("employeeId"));
		//String dismissDate = StringUtil.parseString(param.get("dismissDate"));
		
		try {
			Example example_tmp = new Example(OrgElement.class);
			example_tmp.createCriteria().andEqualTo("fdIsAvailable", (short)1).andEqualTo("fdImportInfo", OAWebServiceInClient.APPNAME+employeeId).andEqualTo("fdOrgType", 8L);
			OrgElement orgElement1 =  orgElementDAO.selectOneByExample(example_tmp);
			
			StringBuilder content = new StringBuilder();
			content.append("<h1>人力系统人员信息变动，请注意删除以下员工信息</h1><br/><pre>");
			content.append("工号：");content.append(orgElement1.getFdNo());content.append("\r\n");
			content.append("姓名：");content.append(orgElement1.getFdName());content.append("\r\n");
			content.append("</pre>");
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
	    	MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", content.toString());
			
			OAWebServiceInClient.deletePerson(employeeId);
			MailUtil.disableEmail(orgElement1.getFdOrgEmail());
		} catch (Exception e) {
			logger.error("deletePerson error",e);
		}
 	}
 	
 	private StringBuilder updateContent = new StringBuilder();
 	
 	/**
 	 * 回调时同步
 	 * @param param
 	 */
 	public void synchronizeWhenCallBack(Map<String,Object> param) {
		Object type = param.get("type");
		
		Thread t = new Thread(new Runnable() {
			public void run() {
				if("department_create".equals(type)) {//创建部门
					addDepartment(param);
				}else if("department_update".equals(type)) {//更新部门
					updateDepartment(param);
				}else if("department_delete".equals(type)) {//删除部门
					deleteDepartment(param);
				}else if("employee_entry".equals(type)) {//新增员工
					String employeeId = StringUtil.parseString(param.get("employeeId"));
//					String name = StringUtil.parseString(param.get("name"));
//					String mobile = StringUtil.parseString(param.get("mobile"));
//					mobile= mobile.replaceAll("[^0-9]", "");
//					String entryDate = StringUtil.parseString(param.get("entryDate"));
//					String hireType = StringUtil.parseString(param.get("hireType"));//0 正式，10 实习，11劳务，12顾问，13 返聘
//					Map<String,Object> otherFields = (Map<String, Object>) param.get("fields");
//					String departmentId = StringUtil.parseString(otherFields.get("部门"));
					addPerson(employeeId);
				}else if("employee_update".equals(type)) {//更新员工信息
					StringBuilder returnContent = updatePerson(param);
					synchronized(updateContent) {
						updateContent.append(returnContent);
					}
					
				}else if("employee_dismiss".equals(type)) {//员工离职
					deletePerson(param);
				}else if("employee_delete".equals(type)) {//删除员工
					deletePerson(param);
				}
			
		    	try {
					if(updateContent.length()>10000) {
						sendUpdatePersonNotice();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		});
		
		t.start();
		
		
		Thread mailThread= new Thread(new Runnable() {
			public void run() {
				try {
					Thread.sleep(1000*60*5);
					sendUpdatePersonNotice();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		mailThread.start();
 	}
 	
 	private void sendUpdatePersonNotice() throws Exception {
 		
 		StringBuilder sb = new StringBuilder();
		synchronized(updateContent) {
			sb.append(updateContent);
			updateContent.delete(0, updateContent.length());
		}
 		
 		if(sb.length()>0) {
			Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
			Set<String> receiveMailAccounts1 = SysConfig.getSysSet("人力管理员接收邮箱");
			if(receiveMailAccounts1==null) {
				receiveMailAccounts.addAll(receiveMailAccounts1);
			}
			MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", "<pre>"+sb.toString()+"</pre>");
		}
 	}
 	
 	
 
 	/**
 	 * OA所有部门
 	 */
 	private Map<String,OrgElementWithPerson> oaDeptMap;
 	/**
 	 * OA所有员工
 	 */
 	private Map<String,OrgElementWithPerson> oaPersonMap; 
 	/**
 	 * 比较后获得所有应存在的员工和部门列表
 	 */
 	private Map<String,OrgElementWithPerson> oaOrgMap_should_exist;
 	/**
 	 * OA公司信息，作为一级部门的上级部门
 	 */
 	private OrgElement company;
 	
	/**
 	 * OA公司信息，作为一级部门的上级部门
 	 */
 	private OrgElement sysPosition;
 	
 	public void synchronizeWhenTimeout() throws Exception {
 		/*
 		 * 查询OA所有部门
 		 */
 		oaDeptMap = new HashMap<>();
		oaPersonMap = new HashMap<>();
		oaOrgMap_should_exist = new HashMap<>();//应该存在的部门
		List<OrgElementWithPerson> oa_dept_list =  orgElementWithPersonDAO.selectOrgWithPerson();
		for(OrgElementWithPerson orgElement:oa_dept_list) {
			if(orgElement.getFdOrgType()==2) {//部门
				if(orgElement.getFdName().equals("沣邦融资租赁（上海）有限公司")) {
					company = orgElement;
					continue;
				}
				String xrxsId = orgElement.getFdImportInfo();
				if(xrxsId!=null) {
					oaDeptMap.put(orgElement.getFdImportInfo().replace(OAWebServiceInClient.APPNAME, ""), orgElement);
				}else {
					oaDeptMap.put(orgElement.getFdNo(), orgElement);
				}
				
			}else if(orgElement.getFdOrgType()==8){ //人员
				String xrxsId = orgElement.getFdImportInfo();
				if(xrxsId!=null) {
					oaPersonMap.put(orgElement.getFdImportInfo().replace(OAWebServiceInClient.APPNAME, ""), orgElement);
				}else {
					oaPersonMap.put(orgElement.getFdNo(), orgElement);
				}
				
			}else if(orgElement.getFdName().equals("OA系统虚拟岗位")) {
				sysPosition = orgElement;
			}
		}
		
		/*
 		 * 查询XRXS所有一级部门
 		 */
		Map<String,XRXSDept> xrxsDeptMap = XRXSReqClient.getAllDepts("",false);
		
		/*
		 * 比较组织架构，新增或更新
		 */
		compareAndUpdate(xrxsDeptMap);
		
		/*
		 *比较并删除应禁用的部门和员工	
		 */
		compareAndDelete();
 	}
 	
 	/**
 	 * 以XRXS为准，比较组织架构，更新OA
 	 * @param xrxsDeptMap				XRXS部门列表
 	 * @throws Exception
 	 */
 	private void compareAndUpdate(Map<String,XRXSDept> xrxsDeptMap) throws Exception {
		
 		/*
 		 * 遍历比较部门
 		 */
		for(Iterator<String> xrxsDeptIt =xrxsDeptMap.keySet().iterator();xrxsDeptIt.hasNext();) {
			String xrxsDeptId = xrxsDeptIt.next();
			XRXSDept xrxsDept = xrxsDeptMap.get(xrxsDeptId);
			OrgElementWithPerson oaDepart = oaDeptMap.get(xrxsDeptId);
			
			oaDepart = compareAndUpdateDept(oaDepart, xrxsDept);
			oaOrgMap_should_exist.put(xrxsDeptId, oaDepart);
			
			Map<String,XRXSPerson> xrxsPersonsMap =XRXSReqClient.getDeptDetailUsers(xrxsDeptId);
			for(Iterator<String> xrxsPersonIt =xrxsPersonsMap.keySet().iterator();xrxsPersonIt.hasNext();) {
				String xrxsPersonId = xrxsPersonIt.next();
				XRXSPerson xrxsPerson = xrxsPersonsMap.get(xrxsPersonId);
				
				OrgElementWithPerson oaPerson = oaPersonMap.get(xrxsPersonId);
				oaPerson = compareAndUpdatePerson(oaPerson, xrxsPerson);
				oaOrgMap_should_exist.put(xrxsPersonId, oaPerson);
			}
			
			/*
			 * 如果存在子部门，则递归处理
			 */
//			Map<String,XRXSDept> xrxsDeptChildrenMap = XRXSReqClient.getAllDepts(xrxsDeptId,false);
//			if(xrxsDeptChildrenMap.size()>1) {
//				compareAndUpdate(xrxsDeptChildrenMap);
//			}
		}
 	}
 
 	
 	/**
 	 * 比较部门
 	 * @param orgElement
 	 * @param xrxsDept
 	 * @return
 	 * @throws Exception
 	 */
 	private OrgElementWithPerson compareAndUpdateDept(OrgElementWithPerson orgElement,XRXSDept xrxsDept ) {
 		String xrxsDeptId = xrxsDept.getDepartmentId();
 		
 		if(orgElement==null) {
 			/*
 			 * 如果OA系统已有的同一个编号的部门，则更新importInfo字段
 			 */
 			orgElement = oaDeptMap.get(xrxsDept.getCode());
			if(orgElement!=null) {
				orgElement.setFdImportInfo(OAWebServiceInClient.APPNAME+xrxsDeptId);
				OrgElement deptOrg = new OrgElement();
				BeanUtils.copyProperties(orgElement, deptOrg);
				orgElementDAO.updateByPrimaryKeySelective(deptOrg);
			}
		}
 		
 		if(orgElement==null) {
			//oa 不存在本部门，则新增
			try {
				OAWebServiceInClient.addDepartment(xrxsDeptId, xrxsDept.getCode(), xrxsDept.getName(), xrxsDept.getParentId(),xrxsDept.getAdminId());
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("addDepartment error:"+xrxsDept,e);
			}
			
			//查询新增的部门放在map中去
			Example example_tmp = new Example(OrgElement.class);
			example_tmp.createCriteria().andEqualTo("fdIsAvailable", (short)1).andEqualTo("fdName", xrxsDept.getName()).andEqualTo("fdOrgType", 2L);
			OrgElement orgElement_oa =  orgElementDAO.selectOneByExample(example_tmp);
			if(orgElement_oa!=null) {
				orgElement = new OrgElementWithPerson();
				BeanUtils.copyProperties(orgElement_oa, orgElement);
				oaDeptMap.put(xrxsDeptId,orgElement);
			}
		}else {
			//比较 部门名称，上级部门
			String xrxsName = xrxsDept.getName().trim();
			String xrxsParentId = xrxsDept.getParentId();
			String xrxsLeaderId = xrxsDept.getAdminId();
			
			String oaName = orgElement.getFdName().trim();
			String oaParentId = orgElement.getFdParentid();
			String oaLeaderId = orgElement.getFdThisLeaderid();
			
			boolean updateflag = false;
			
			//比较部门名称，不一致则更新OA
			if(!xrxsName.equals(oaName)) {
				orgElement.setFdName(xrxsName);
				updateflag = true;
			}
			
			//比较上级部门，不一致则更新OA
			if(xrxsParentId.equals("")) {
				//如果为一级部门
				if(!company.getFdId().equals(oaParentId)) {
					orgElement.setFdHierarchyId(company.getFdHierarchyId()+orgElement.getFdId()+"x");
					orgElement.setFdParentid(company.getFdId());
					updateflag = true;
				}
			}else {
				OrgElement parent = oaDeptMap.get(xrxsParentId);
				if(!parent.getFdId().equals(oaParentId)) {
					orgElement.setFdHierarchyId(parent.getFdHierarchyId()+orgElement.getFdId()+"x");
					orgElement.setFdParentid(parent.getFdId());
					updateflag = true;
				}
			}
			
			//比较部门负责人，不一致则更新OA
//			if(!StringUtil.isBlank(xrxsLeaderId)) {
//				OrgElementWithPerson xrxsLeader = oaPersonMap.get(xrxsLeaderId);
//				
//				if(xrxsLeader==null) {
//					//创建此用户
//					XRXSPerson xrxsPerson = this.addPerson(xrxsLeaderId);
//					
//					//查询此新用户
//					Example example_tmp = new Example(OrgElement.class);
//					example_tmp.createCriteria().andEqualTo("fdIsAvailable", (short)1).andEqualTo("fdImportInfo", OAWebServiceInClient.APPNAME+xrxsLeaderId).andEqualTo("fdOrgType", 8L);
//					OrgElement orgElement1 =  orgElementDAO.selectOneByExample(example_tmp);
//					xrxsLeader = new OrgElementWithPerson();
//					BeanUtils.copyProperties(orgElement1, xrxsLeader);
//					oaPersonMap.put(xrxsLeaderId,xrxsLeader);
//				}
//				
//				if(!xrxsLeader.getFdId().equals(oaLeaderId)) {
//					orgElement.setFdThisLeaderid(xrxsLeader.getFdId());
//					updateflag = true;
//				}
//			}else {
//				orgElement.setFdThisLeaderid(sysPosition.getFdId());
//				updateflag = true;
//			}
			
			
			if(updateflag) {
				OrgElement orgElement_new  = new OrgElement();
				BeanUtils.copyProperties(orgElement, orgElement_new);
				orgElementDAO.updateByPrimaryKeySelective(orgElement_new);
			}
			
		}
 		
 		return orgElement;
 	}
 	
 	/**
 	 * 比较人员
 	 * @param oaPerson
 	 * @param xrxsPerson
 	 * @return
 	 * @throws Exception
 	 */
 	private OrgElementWithPerson compareAndUpdatePerson(OrgElementWithPerson oaPerson,XRXSPerson xrxsPerson){
 		
 		String name = xrxsPerson.getName().trim();
 		String fdNo = xrxsPerson.getFdNo();
 		String mobile = xrxsPerson.getMobile();
 		String tel = xrxsPerson.getTel();
 		String departmentId = xrxsPerson.getDepartmentId();
 		
 		String employeeId = xrxsPerson.getUserId();
 		String title = xrxsPerson.getTitle();
 		String gender = xrxsPerson.getGender();
 		String entryDate = xrxsPerson.getEntryDate();
 		String hireType = xrxsPerson.getHireType();
 		String rank = xrxsPerson.getRank();
 		String password = "Fb"+mobile;
 		
 		if(oaPerson==null) {
			oaPerson = oaPersonMap.get(xrxsPerson.getFdNo());
			if(oaPerson!=null) {
				oaPerson.setFdImportInfo(OAWebServiceInClient.APPNAME+employeeId);
				OrgElement perOrg = new OrgElement();
				BeanUtils.copyProperties(oaPerson, perOrg);
				orgElementDAO.updateByPrimaryKeySelective(perOrg);
			}
		}
 		
 		if(oaPerson==null) {
			//oa 不存在本员工，则新增
 			//创建此用户
			xrxsPerson = this.addPerson(employeeId, departmentId, name, title, mobile, tel, fdNo, gender, entryDate, hireType, rank, password);

			//查询此新用户
			Example example_tmp = new Example(OrgElementWithPerson.class);
			example_tmp.createCriteria().andEqualTo("fdIsAvailable", (short)1).andEqualTo("fdImportInfo", OAWebServiceInClient.APPNAME+employeeId).andEqualTo("fdOrgType", 8L);
			OrgElement oaPerson1 =  orgElementDAO.selectOneByExample(example_tmp);
			oaPerson = new OrgElementWithPerson();
			if(oaPerson1==null) {
				throw new RuntimeException("创建用户失败\r\nname:"+name+",no:"+fdNo+",mobile:"+mobile+",xrxsId:"+employeeId);
			}
			
			BeanUtils.copyProperties(oaPerson1, oaPerson);
			oaPersonMap.put(employeeId,oaPerson);
			
			/*
			 * 设置OA用户职级
			 */
			Example example_level = new Example(OAStaffLevel.class);
			example_level.createCriteria().andEqualTo("fdName", rank);
			OAStaffLevel staffLevel = oAStaffLevelDAO.selectOneByExample(example_level);
			if(staffLevel!=null) {
				Person newPerson = new Person();
				newPerson.setFdMobileNo(mobile);
				newPerson.setFdStaffingLevelId(staffLevel.getFdId());
				Example example = new Example(Person.class);
				example.createCriteria().andEqualTo("fdMobileNo", mobile);
				personDAO.updateByExampleSelective(newPerson, example);
			}
			
		}else {
			//比较 名称，工号，部门，手机，固话,职级
			
			String oaName = oaPerson.getFdName().trim();
			String oaFdNo = oaPerson.getFdNo();
			String oaMobile = oaPerson.getFdMobileNo();
			String oaTel = oaPerson.getFdWorkPhone();
			String oaDepartmentId = oaPerson.getFdParentid();
			String oaRank=oaPerson.getFdStaffingLevelName();
			
			boolean updateflag = false;
			//比较名称，不一致则更新OA
			if(!name.equals(oaName)) {
				updateflag = true;
			}
			
			//比较工号，不一致则更新OA
			if(!fdNo.equals(oaFdNo)) {
				updateflag = true;
			}
			
			//比较手机，不一致则更新OA
			if(!mobile.equals(oaMobile)) {
				updateflag = true;
			}
			
			//比较固话，不一致则更新OA
//			if(!tel.equals(oaTel)) {
//				updateflag = true;
//			}
			
			if(!rank.equals(oaRank)) {
				updateflag = true;
				/*
				 * 设置OA用户职级
				 */
				Example example_level = new Example(OAStaffLevel.class);
				example_level.createCriteria().andEqualTo("fdName", rank);
				OAStaffLevel staffLevel = oAStaffLevelDAO.selectOneByExample(example_level);
				if(staffLevel!=null) {
					Person newPerson = new Person();
					newPerson.setFdMobileNo(mobile);
					newPerson.setFdStaffingLevelId(staffLevel.getFdId());
					Example example = new Example(Person.class);
					example.createCriteria().andEqualTo("fdMobileNo", mobile);
					personDAO.updateByExampleSelective(newPerson, example);
				}
			}
			
			String xrxsDepartId = oaDeptMap.get(departmentId).getFdId();
			//比较部门，不一致则更新OA
			if(!xrxsDepartId.equals(oaDepartmentId)) {
				updateflag = true;
			}
			
			if(updateflag) {
				try {
					OAWebServiceInClient.updatePerson(employeeId, fdNo, name,gender.equals("男")?"M":"F",mobile, oaTel,  departmentId);
				} catch (Exception e) {
					logger.error("更新员工信息报错："+xrxsPerson,e);
					e.printStackTrace();
				}
			}
			
		}
 		
 		return oaPerson;
 	}

 	/**
 	 * 比较并删除应删除的部门和员工
 	 */
 	private void compareAndDelete() {
 		String file = "org_elements_waiting2delete.txt";
 	 	StringBuilder content = new StringBuilder();
 	 	for(Iterator<String> it =oaDeptMap.keySet().iterator();it.hasNext();) {
 	 		String key = it.next();
 	 		if(oaOrgMap_should_exist.get(key)==null) {
 	 			OrgElement depart = oaDeptMap.get(key);
 	 			depart.setFdIsAvailable((short) 0);
// 	 			orgElementDAO.updateByPrimaryKeySelective(depart);
 	 			FileUtil.writeTxt2File(depart.getFdName(), file);
 	 			content.append(depart.getFdName()+"-"+depart.getFdNo());
 	 			content.append("\r\n");
 	 		}
 	 	}
 	 	
 		for(Iterator<String> it =oaPersonMap.keySet().iterator();it.hasNext();) {
 	 		String key = it.next();
 	 		if(oaOrgMap_should_exist.get(key)==null) {
 	 			OrgElement person = oaPersonMap.get(key);
 	 			person.setFdIsAvailable((short) 0);
// 	 			orgElementDAO.updateByPrimaryKeySelective(person);
 	 			FileUtil.writeTxt2File(person.getFdName(), file);
 	 			content.append(person.getFdName()+"-"+person.getFdNo());
 	 			content.append("\r\n");
 	 		}
 	 	}
 	 	
 		Set<String> receiveMailAccounts = SysConfig.getSysSet("邮箱管理员接收邮箱");
		receiveMailAccounts.clear();
		receiveMailAccounts.add("sushaolei@fengbangleasing.com");
    	try {
			MailUtil.sendMail(receiveMailAccounts.toArray(new String[0]), DateUtil.date2Str(new Date(), "yyyyMMdd")+"-OA组织架构同步通知", "薪人薪事已离职员工如下：<br/><pre>"+content.toString()+"</pre>");
		} catch (Exception e) {
			e.printStackTrace();
		}

 	}
}